package com.np.storage_demo1;

import androidx.appcompat.app.AppCompatActivity;

import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import java.util.ArrayList;
import java.util.List;

/*
 * 什么是SQLiteDatabase？
 * 一个SQLiteDatabase的实例代表了一个SQLite的数据库，通过SQLiteDatabase实例的一些方法，我们可以执行SQL语句，
 * 对数据库进行增、删、查、改的操作。需要注意的是，数据库对于一个应用来说是私有的，并且在一个应用当中，数据库的名字也是惟一的。

 * 什么是SQLiteOpenHelper？
 * 这个类主要生成一个数据库，并对数据库的版本进行管理。
 * 当在程序当中调用这个类的方法getWritableDatabase()或者getReadableDatabase()方法的时候，如果当时没有数据，那么Android系统就会自动生成一个数据库。
 * SQLiteOpenHelper 是一个抽象类，我们通常需要继承它，并且实现里边的3个函数，
 *     onCreate（SQLiteDatabase）：在数据库第一次生成的时候会调用这个方法，一般我们在这个方法里边生成数据库表。
 *     onUpgrade（SQLiteDatabase, int, int）：当数据库需要升级的时候，Android系统会主动的调用这个方法。一般我们在这个方法里边删除数据表，并建立新的数据表，当然是否还需要做其他的操作，完全取决于应用的需求。
 *     onOpen（SQLiteDatabase）：这是当打开数据库时的回调函数，一般也不会用到。
 */
public class SqliteActivity extends AppCompatActivity {

    private static final String TAG = SqliteActivity.class.getSimpleName();
    private static final String DATABASE_NAME = "app_demo.db";
    private static final int DATABASE_VERSION = 1;
    private static final String TABLE_NAME = "note";
    private static final String COLUMN_TITLE = "title";
    private static final String COLUMN_CONTENT = "content";
    private DatabaseHelper mDBHelper;
    private List<NoteEntity> mNoteList;
    private NoteAdapter mAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_sqlite);

        mDBHelper = new DatabaseHelper(this);
        mNoteList = new ArrayList<>();
        mAdapter = new NoteAdapter(this);

        ListView lvNode = findViewById(R.id.lv_node);
        lvNode.setAdapter(mAdapter);

        // create table
        findViewById(R.id.button1).setOnClickListener(v -> {
            SQLiteDatabase db = mDBHelper.getWritableDatabase();
            db.execSQL(String.format("CREATE TABLE IF NOT EXISTS %s (%s text not null, %s text not null);", TABLE_NAME, COLUMN_TITLE, COLUMN_CONTENT));
            Toast.makeText(this, "Operation successful!", Toast.LENGTH_SHORT).show();
        });

        // drop table
        findViewById(R.id.button2).setOnClickListener(v -> {
            SQLiteDatabase db = mDBHelper.getWritableDatabase();
            db.execSQL(String.format("DROP TABLE IF EXISTS %s", TABLE_NAME));
            Toast.makeText(this, "Operation successful!", Toast.LENGTH_SHORT).show();
        });

        // insert
        findViewById(R.id.button3).setOnClickListener(v -> {
            SQLiteDatabase db = mDBHelper.getWritableDatabase();
            db.execSQL(String.format("INSERT INTO %s (%s, %s) values ('%s', '%s')", TABLE_NAME, COLUMN_TITLE, COLUMN_CONTENT, "Trump", "Make america great again!"));
            db.execSQL(String.format("INSERT INTO %s (%s, %s) values ('%s', '%s')", TABLE_NAME, COLUMN_TITLE, COLUMN_CONTENT, "Biden", "Help me up!"));
            db.execSQL(String.format("INSERT INTO %s (%s, %s) values ('%s', '%s')", TABLE_NAME, COLUMN_TITLE, COLUMN_CONTENT, "Senator", "If i am not at home, will TikTok play with my wife?"));
            Toast.makeText(this, "Operation successful!", Toast.LENGTH_SHORT).show();
        });

        // delete
        findViewById(R.id.button4).setOnClickListener(v -> {
            SQLiteDatabase db = mDBHelper.getWritableDatabase();
            db.delete(TABLE_NAME, "title = 'Trump'", null);
            db.delete(TABLE_NAME, "title = ?", new String[]{"Biden"});
            Toast.makeText(this, "Operation successful!", Toast.LENGTH_SHORT).show();
        });

        // select
        findViewById(R.id.button5).setOnClickListener(v -> {
            if (!mDBHelper.isTableExits(TABLE_NAME)) {
                String msg = String.format("Table %s is not exists!", TABLE_NAME);
                Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();
                return;
            }

            /*
             * 在屏幕的title区域显示当前数据表当中的数据的条数。
             *
             * Cursor cur = db.query(TABLE_NAME, col, null, null, null, null, null)语句将查询到的数据放到一个Cursor 当中。
             * 这个Cursor里边封装了这个数据表TABLE_NAME当中的所有条列。
             * query()方法相当的有用，在这里我们简单地讲一下。
             * 第一个参数是数据库里边表的名字，比如在我们这个例子，表的名字就是TABLE_NAME，也就是"diary"。
             * 第二个字段是我们想要返回数据包含的列的信息。在这个例子当中我们想要得到的列有title、content。我们把这两个列的名字放到字符串数组里边来。
             * 第三个参数为selection，相当于SQL语句的where部分，如果想返回所有的数据，那么就直接置为null。
             * 第四个参数为selectionArgs。在selection部分，你有可能用到“?”，那么在selectionArgs定义的字符串会代替selection中的“?”。
             * 第五个参数为groupBy。定义查询出来的数据是否分组，如果为null则说明不用分组。
             * 第六个参数为having ，相当于SQL语句当中的having部分。
             * 第七个参数为orderBy，来描述我们期望的返回值是否需要排序，如果设置为null则说明不需要排序。
             */
            SQLiteDatabase db = mDBHelper.getWritableDatabase();
            Cursor cur = db.query(TABLE_NAME, new String[]{COLUMN_TITLE, COLUMN_CONTENT}, null, null, null, null, null);

            if (cur != null) {
                if (mNoteList != null) {
                    mNoteList.clear();
                }

                while (cur.moveToNext()) {
                    String title = cur.getString(0);
                    String content = cur.getString(1);

                    mNoteList.add(new NoteEntity(title, content));
                }
            }

            mAdapter.notifyDataSetChanged();

            Toast.makeText(this, "rows: " + cur.getCount(), Toast.LENGTH_SHORT).show();
        });
    }

    private class DatabaseHelper extends SQLiteOpenHelper {

        DatabaseHelper(Context context) {
            super(context, DATABASE_NAME, null, DATABASE_VERSION);
        }

        //在数据库第一次生成的时候会调用这个方法，一般我们在这个方法里边生成数据库表。
        @Override
        public void onCreate(SQLiteDatabase db) {
            String sql = String.format("CREATE TABLE IF NOT EXISTS %s (%s text not null, %s text not null);", TABLE_NAME, COLUMN_TITLE, COLUMN_CONTENT);
            db.execSQL(sql);
        }

        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

        }

        public boolean isTableExits(String tableName) {
            SQLiteDatabase db = getWritableDatabase();
            Cursor cur = db.rawQuery("select count(*) from sqlite_master where type = 'table' and name = ?", new String[]{tableName});
            if (cur != null) {
                if (cur.moveToNext()) {
                    return cur.getInt(0) > 0;
                }
            }
            return false;
        }
    }

    private class NoteEntity {
        private String title;
        private String content;

        public String getTitle() {
            return title;
        }

        public void setTitle(String title) {
            this.title = title;
        }

        public String getContent() {
            return content;
        }

        public void setContent(String content) {
            this.content = content;
        }

        public NoteEntity(String title, String content) {
            this.title = title;
            this.content = content;
        }
    }

    private class NoteAdapterHolder {
        public TextView title;
        public TextView content;
        public Button btnDelete;
    }

    private class NoteAdapter extends BaseAdapter {

        private Context mContext;
        private LayoutInflater mLayoutInflater;

        public NoteAdapter(Context context) {
            mContext = context;
            mLayoutInflater = LayoutInflater.from(context);
        }

        @Override
        public int getCount() {
            if (mNoteList != null) {
                return mNoteList.size();
            }
            return 0;
        }

        @Override
        public Object getItem(int position) {
            if (mNoteList != null) {
                return mNoteList.get(position);
            }
            return null;
        }

        @Override
        public long getItemId(int position) {
            return 0;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            NoteAdapterHolder holder;

            if (convertView == null) {
                convertView = mLayoutInflater.inflate(R.layout.item_note, parent, false);

                holder = new NoteAdapterHolder();
                holder.title = convertView.findViewById(R.id.tv_title);
                holder.content = convertView.findViewById(R.id.tv_content);
                holder.btnDelete = convertView.findViewById(R.id.btn_delete);

                convertView.setTag(holder);
            } else {
                holder = (NoteAdapterHolder) convertView.getTag();
            }

            NoteEntity entity = (NoteEntity) getItem(position);
            String title = entity.getTitle();
            String content = entity.getContent();

            holder.title.setText(title);
            holder.content.setText(content);
            holder.btnDelete.setOnClickListener(v -> {
                // todo:delete
                Toast.makeText(mContext, title + " has deleted!", Toast.LENGTH_SHORT).show();
            });

            return convertView;
        }
    }
}